﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace InternshipManagement.Models
{
    public class AccountRepository
    {
        private InternshipEntities entities = new InternshipEntities();

        #region User
        //
        // Query Methods
        public IQueryable<User> FindAllUsers()
        {
            return entities.Users;
        }

        public IQueryable<User> FindUserByNameAndType(string UserName,int UserTypeID)
        {
            return entities.Users.Where(u => u.UserName.Contains(UserName)
                                        && (u.UserTypeID == UserTypeID || UserTypeID == 0));
        }

        public User GetUser(string UserName)
        {
            return entities.Users.FirstOrDefault(u => u.UserName.Equals(UserName));
        }

        public bool ValidateUser(string UserName,string Password)
        {
            return entities.Users.FirstOrDefault(u => u.UserName.Equals(UserName) && u.Password.Equals(Password)) != null;
        }

        public bool UserExists(string UserName)
        {
            return entities.Users.FirstOrDefault(u => u.UserName.Equals(UserName)) != null;
        }

        public User GetUserByID(int id)
        {
            return entities.Users.FirstOrDefault(u => u.ID == id);
        }

        public Int32 GetUserTypeID(string UserType)
        {
            return entities.UserTypes.First(ut => ut.UserTypeName.Equals(UserType)).UserTypeID;
        }

        //
        // Insert/Delete Methods
        public void AddUser(User user)
        {
            entities.Users.AddObject(user);
        }
        public void DeleteUser(User user)
        {
            entities.Users.DeleteObject(user);
        }

        #endregion


        #region Student

        public Student GetStudent(int id)
        {
            return entities.Students.FirstOrDefault(s => s.ID == id);
        }

        public IQueryable<Student> FindAllStudents()
        {

            return entities.Students.OrderBy(s=>s.ID);
        }

        public IQueryable<Student> FindAllStudents(int CourseID)
        {

            return entities.Students.Where(s => s.CourseID == CourseID).OrderBy(s => s.ID);
        }


        public void AddStudent(Student student)
        {
            entities.Students.AddObject(student);
        }

        public void DeleteStudent(Student student)
        {
            entities.Students.DeleteObject(student);
        }

        #endregion

        #region Supervisor

        public Supervisor GetSupervisor(string UserName)
        {
            return entities.Supervisors.FirstOrDefault(s => s.User.UserName.Equals(UserName));
        }

        public Supervisor GetSupervisor(int ID)
        {
            return entities.Supervisors.FirstOrDefault(s => s.ID == ID);
        }

        public void AddSupervisor(Supervisor supervisor)
        {
            entities.Supervisors.AddObject(supervisor);
        }

        public void DeleteSupervisor(Supervisor supervisor)
        {
            entities.Supervisors.DeleteObject(supervisor);
        }

        #endregion

        #region Company

        public Company GetCompany(string UserName)
        {
            return entities.Companies.FirstOrDefault(c => c.User.UserName == UserName);
        }

        public Company GetCompany(int id)
        {
            return entities.Companies.FirstOrDefault(c => c.ID == id);
        }

        public void AddCompany(Company company)
        {
            entities.Companies.AddObject(company);
        }

        public IQueryable<Company> FindAllCompanies()
        {

            return entities.Companies.Where(s => 1 == 1).OrderBy(s => s.ID);
        }

        public void DeleteCompany(Company company)
        {
            entities.Companies.DeleteObject(company);
        }

        #endregion

        #region Secretary

        public Secretary GetSecretary(int ID)
        {
            return entities.Secretaries.FirstOrDefault(s => s.ID == ID);
        }

        public void AddSecretary(Secretary secretary)
        {
            entities.Secretaries.AddObject(secretary);
        }

        public void DeleteSecretary(Secretary secretary)
        {
            entities.Secretaries.AddObject(secretary);
        }

        #endregion

        public IQueryable<User> FindAllSupervisorSecretary()
        {
            return entities.Users.Where(u=>u.UserType.UserTypeName == "Supervisor" || u.UserType.UserTypeName == "Secretary").OrderBy(u=>u.UserName);
        }


        #region Priviliges
        public IQueryable<Privilege> FindAllPrivileges()
        {
            return entities.Privileges;
        }

        public IQueryable<UserPrivilege> FindAllUserPrivileges()
        {
            return entities.UserPrivileges;
        }

        public IQueryable<UserPrivilege> FindAllUserPrivileges(int userTypeID)
        {
            return FindAllUserPrivileges().Where(up => up.UserTypeID == userTypeID);
        }

        public List<int> FindAllUserPrivilegesIDs()
        {
            return FindAllUserPrivileges().Select(up => up.PrivilegeID.Value).ToList(); ;
        }

        public List<int> FindAllUserPrivilegesIDs(int userTypeID)
        {
            if(userTypeID == GetUserTypeID("Supervisor"))//TODO
            {
                return FindAllPrivileges().Select(p => p.ID).ToList();
            }
            return FindAllUserPrivileges(userTypeID).Select(up => up.PrivilegeID.Value).ToList(); ;
        }

        public bool PrivilegeExists(int userTypeID,int PrivilegeID)
        {
            return FindAllUserPrivileges().FirstOrDefault(up => up.UserTypeID == userTypeID && up.PrivilegeID == PrivilegeID) != null;
        }

        public void AddUserPrivilege(UserPrivilege userPrivilege)
        {
            entities.UserPrivileges.AddObject(userPrivilege);
        }

        public void RemoveUserPrivilege(UserPrivilege userPrivilege)
        {
            entities.UserPrivileges.DeleteObject(userPrivilege);
        }

        public void RemoveAllUserPrivilege(int userTypeID)
        {
            foreach (UserPrivilege userPrivilege in FindAllUserPrivileges(userTypeID))
            {
                entities.DeleteObject(userPrivilege);
            }
        }

        #endregion


        public IQueryable<string> FindAllEmails(int[] userTypeIDs)
        {
            return from user in entities.Users
                   where userTypeIDs.Contains(user.UserTypeID)
                   select (user.UserTypeID == 4 ? user.UserName + "@gmail.com" : user.UserName);
        }
        //
        // Persistence
        public void Save()
        {
            entities.SaveChanges();
        }
    }
}